package com.breaktian.assemble.utils;

import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.telephony.TelephonyManager;
import android.text.TextUtils;

import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.util.Enumeration;

/**
 * 网络工具类
 * <p/>
 * Created by anyi.li on 2016/12/6.
 */
public final class NetworkUtils {

    /**
     * 无效网络
     */
    public static final int NETWORK_TYPE_INVALID = 0x0000;
    /**
     * WIFI网络
     */
    public static final int NETWORK_TYPE_WIFI = 0x0001;
    /**
     * 2G移动网络
     */
    public static final int NETWORK_TYPE_2G = 0x0002;
    /**
     * 3G移动网络
     */
    public static final int NETWORK_TYPE_3G = 0x0003;
    /**
     * 4G移动网络
     */
    public static final int NETWORK_TYPE_4G = 0x0004;

    /**
     * 网络是否可用
     *
     * @param context Context
     * @return boolean
     */
    public static boolean isNetworkAvailable(Context context) {
        ConnectivityManager connectManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo[] networkInfos = connectManager.getAllNetworkInfo();
        if (networkInfos != null) {
            int length = networkInfos.length;
            for (int i = 0; i < length; i++) {
                NetworkInfo networkInfo = networkInfos[i];
                if (networkInfo != null && networkInfo.isAvailable() && networkInfo.isConnectedOrConnecting()) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * 获取当前网络连接的网络类型
     *
     * @param context Context
     * @return int 网络类型
     * @see #NETWORK_TYPE_INVALID
     * @see #NETWORK_TYPE_WIFI
     * @see #NETWORK_TYPE_2G
     * @see #NETWORK_TYPE_3G
     * @see #NETWORK_TYPE_4G
     */
    public static int getNetworkType(Context context) {
        ConnectivityManager connectManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo networkInfo = connectManager.getActiveNetworkInfo();

        if (networkInfo != null) {
            if (networkInfo.isConnected()) {
                if (networkInfo.getType() == ConnectivityManager.TYPE_WIFI) {
                    return NETWORK_TYPE_WIFI;
                } else if (networkInfo.getType() == ConnectivityManager.TYPE_MOBILE) {
                    int subtype = networkInfo.getSubtype();
                    switch (subtype) {
                        case TelephonyManager.NETWORK_TYPE_UNKNOWN:
                            return NETWORK_TYPE_INVALID;
                        case TelephonyManager.NETWORK_TYPE_GPRS:
                        case TelephonyManager.NETWORK_TYPE_EDGE:
                        case TelephonyManager.NETWORK_TYPE_CDMA:
                        case TelephonyManager.NETWORK_TYPE_1xRTT:
                        case TelephonyManager.NETWORK_TYPE_IDEN:
                            return NETWORK_TYPE_2G;
                        case TelephonyManager.NETWORK_TYPE_UMTS:
                        case TelephonyManager.NETWORK_TYPE_EVDO_0:
                        case TelephonyManager.NETWORK_TYPE_EVDO_A:
                        case TelephonyManager.NETWORK_TYPE_HSDPA:
                        case TelephonyManager.NETWORK_TYPE_HSUPA:
                        case TelephonyManager.NETWORK_TYPE_HSPA:
                        case TelephonyManager.NETWORK_TYPE_EVDO_B:
                        case 14://TelephonyManager.NETWORK_TYPE_EHRPD
                        case 15://TelephonyManager.NETWORK_TYPE_HSPAP
                            return NETWORK_TYPE_3G;
                        case 13://TelephonyManager.NETWORK_TYPE_LTE，4G网络
                            return NETWORK_TYPE_4G;
                        default: {
                            String subtypeName = networkInfo.getSubtypeName();
                            if (!TextUtils.isEmpty(subtypeName) &&
                                    (subtypeName.equalsIgnoreCase("TD-SCDMA") ||
                                            subtypeName.equalsIgnoreCase("WCDMA") ||
                                            subtypeName.equalsIgnoreCase("CDMA2000"))) {
                                return NETWORK_TYPE_3G;
                            }
                        }
                    }
                }
            }
        }

        return NETWORK_TYPE_INVALID;
    }

    /**
     * 获取当前网络连接的网络类型(none,2G,3G,4G,wifi)
     *
     * @param context Context
     * @return 网络类型
     */
    public static String getNet(@NonNull Context context) {
        int netType = getNetworkType(context);
        String net;
        switch (netType) {
            case NETWORK_TYPE_INVALID:
                net = "none";
                break;
            case NETWORK_TYPE_2G:
                net = "2G";
                break;
            case NETWORK_TYPE_3G:
                net = "3G";
                break;
            case NETWORK_TYPE_4G:
                net = "4G";
                break;
            case NETWORK_TYPE_WIFI:
                net = "wifi";
                break;
            default:
                net = "none";
        }
        return net;
    }

    /**
     * 获取设备的IP地址(IPv4)
     *
     * @param context Context
     * @return IP地址，格式：000.000.000.000或null
     */
    @Nullable
    public static String getIpAddress(@NonNull Context context) {
        try {
            for (Enumeration<NetworkInterface> enNetI = NetworkInterface.getNetworkInterfaces(); enNetI.hasMoreElements(); ) {
                NetworkInterface netI = enNetI.nextElement();
                for (Enumeration<InetAddress> enumIpAddr = netI.getInetAddresses(); enumIpAddr.hasMoreElements(); ) {
                    InetAddress inetAddress = enumIpAddr.nextElement();
                    if (inetAddress instanceof Inet4Address && !inetAddress.isLoopbackAddress()) {
                        return inetAddress.getHostAddress();
                    }
                }
            }
        } catch (Throwable e) {
        }
        return null;
    }

    private NetworkUtils() {
    }
}
